Android进阶八:RecyclerView自动滚动 |
您所在的位置:网站首页 › 安卓 自动滚屏幕 › Android进阶八:RecyclerView自动滚动 |
smoothScrollToPosition()
在使用RecyclerView的时候,有一些场景需要RecyclerView能自动滑动到指定的item,这种情况可以调用RecyclerView的以下方法来实现: scrollToPosition(int position) smoothScrollToPosition(int position)这两个方法传入需要滑动到的item的position就可以实现跳转到相应的item,区别是scrollToPosition()会立即跳转到相应item,不会有滑动的效果,smoothScrollToPosition()跳转的同时,会有滑动的效果,但是滑动速度很快,用户体验效果不好,如何能控制速度达到一个好的效果呢? 先来看下smoothScrollToPosition()的源码: public void smoothScrollToPosition(int position) { if (mLayoutFrozen) { return; } if (mLayout == null) { Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. " + "Call setLayoutManager with a non-null argument."); return; } mLayout.smoothScrollToPosition(this, mState, position); }它最终是调用了mLayout.smoothScrollToPosition(this, mState, position),mLayout是RecyclerView的布局管理器,比如线性布局管理器LinearLayoutManager: mRecyclerView.setLayoutManager(mLinearLayoutManager);来看下smoothScrollToPosition()在线性布局管理器中的实现: @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); }使用的是LinearSmoothScroller进行滑动操作,再来看LinearSmoothScroller类,它有一个获取滑动速度的方法: protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; }所以我们可以想办法重写这个方法来改变RecyclerView滑动的速度。 我们自定义一个LinearLayoutManager: public class ScrollLinearLayoutManager extends LinearLayoutManager { private static final float MILLISECONDS_PER_INCH = 25f; public ScrollLinearLayoutManager(Context context) { super(context); } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, final int position) { LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) { @Nullable @Override public PointF computeScrollVectorForPosition(int targetPosition) { return ScrollLinearLayoutManager.this.computeScrollVectorForPosition(targetPosition); } @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; } }; linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } }重写smoothScrollToPosition()方法,然后重新实例化一个LinearSmoothScroller,并重写calculateSpeedPerPixel()方法, 这样,可以调整MILLISECONDS_PER_INCH的值,来实现RecyclerView滑动速度的调整。 补充由当前item到目标item的中间要滑动的item数量可能每次都不一样,这样固定的移动速度也会导致用户体验不好,所以可以根据需要滑动的item数量来动态的调整滑动速度, 我们再修改下calculateSpeedPerPixel(): protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { View view = getChildAt(0); if(view != null) { final int firstChildPos = getPosition(getChildAt(0)); //获取当前item的position int delta = Math.abs(position - firstChildPos);//算出需要滑动的item数量 if(delta == 0) delta = 1; return (MILLISECONDS_PER_INCH/delta) / displayMetrics.densityDpi; } else { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; } }这样当需要滑动的item数量越多,滑动速度越快,item数量少时,滑动会较慢,这样就会有一个好的用户体验。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |